<?php
/** Yz_SQL_Statement_Insert
 *
 *
 * The UPDATE statement has some capacities which are useless or even harmful for INSERT
 * - where/order/limit clauses
 * -
 *
*
*/

class Yz_SQL_Statement_Insert
    extends Yz_SQL_DMLStatement
    implements Yz_SQL_Statement_Interface
{

    const CLAUSE_INSERT = 'INSERT';
    const CLAUSE_IGNORE = 'IGNORE';
    const CLAUSE_INTO   = 'INTO';
    const CLAUSE_TABLES = '_tables_';
    const CLAUSE_FIELDS = '_fields_';
    const CLAUSE_VALUES = '_values_';
    const CLAUSE_VALUES_VALUES   = 'VALUES';

    protected $clauses = array(
        self::CLAUSE_INSERT => '',
        self::CLAUSE_IGNORE => '',
        self::CLAUSE_INTO   => '',
        self::CLAUSE_TABLES => '',
        self::CLAUSE_FIELDS => '',
        self::CLAUSE_VALUES => '',
    );

    protected $insertId = false;

    public function insert($table)
    {
        $this->clauses[self::CLAUSE_INSERT] = self::CLAUSE_INSERT;
        return $this->_table(self::CLAUSE_INTO, $table, null);
    }

    public function insertInto( $table )
    {
        return $this->insert($table);
    }


    public function ignore( $ignore=true )
    {
        $this->clauses[self::CLAUSE_IGNORE] = $ignore ? self::CLAUSE_IGNORE : "";

        return $this;
    }

    public function getInsertId()
    {
        $this->testQueryDone();
        return $this->db->getInsertId();
    }


    /**
     *  @param mixed fields : string | array[ name ]
     *  @param mixed values : null | string | array[ field-name => {":var"|SQL clause} ]
     *  @see Yz_SQL_DMLStatement::set()
     */
    public function set( $fields, $values=null )
    {
        if (null === $values) {
            $fields = new Yz_Hash($fields);
            $values = $fields->values();
            $fields = $fields->keys();
        }
        return $this
            ->fields($fields)
            ->values($values);
    }


    /**
     *  @param hash-type|null fields
     *  TODO in combination with values() used for multiple row inserts
     */
    public function fields( $fields )
    {
        debug();
        if (func_num_args() > 1)
            $fields = func_get_args();
        if (null === $fields) {
            $fieldsClause = "";
        } else if (is_string($fields)) {
            $fieldsClause = "({$fields})";
        } else {
            $fields = Yz_Array::valueOf($fields);
            if (null === $fields)
                throw TypeError::_new_();
            $fieldsClause = "(\n  " . join(",\n  ", $fields) . "\n)";
        }
        $this->sql = null;
        $this->clauses[self::CLAUSE_FIELDS] = $fieldsClause;
        return $this;
    }

    /**
     *  TODO multiple row insert
     *  TODO check that the names are the same as in fields()
     *  @param hash-type|null fields
     *
     */
    public function values( $values )
    {
        debug();
        if (func_num_args() > 1)
            $values = func_get_args();
        if (null === $values) {
            $valuesClause = " ()";
        } else if (is_string($values)) {
            $valuesClause = " ({$values})";
        } else {
            $values = Yz_Array::valueOf($values);
            if (null === $values)
                throw TypeError::_new_();
            $valuesClause = "\n(\n  " . join(",\n  ", $values) . "\n)";
        }

        $this->sql = null;
        $this->clauses[self::CLAUSE_VALUES] = self::CLAUSE_VALUES_VALUES . $valuesClause;
        return $this;
    }



    /**
     *  TODO also check if INSERT ... SELECT is done
     *  @return string SQL
     */
    protected function isComplete()
    {
        debug();

        $clauses = $this->clauses;

        return  "" !== $clauses[self::CLAUSE_INSERT]
            and "" !== $clauses[self::CLAUSE_VALUES]
            and "" !== $clauses[self::CLAUSE_TABLES]
        ;
    }


} // class

